﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Wenyu.Framework.WebCore.ToolServices;

namespace Wenyu.Framework.WebCore.AuthorizationExtend
{
    public static class AuthorizationExtension
    {
        /// <summary>
        /// 配置鉴权和授权
        /// </summary>
        /// <param name="service"></param>
        public static void AddAuthorizationExt(this WebApplicationBuilder builder)
        {
            JwtTokenOption jwtTokenOption = new JwtTokenOption();
            builder.Configuration.Bind("JwtTokenOption", jwtTokenOption);
            builder.Services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  //nuget ：Microsoft.AspNetCore.Authentication.JwtBearer
                .AddJwtBearer(options =>     //nuget ：Microsoft.AspNetCore.Authentication.JwtBearer
                {
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = true, //是否验证Issuer
                        ValidateAudience = true,//是否验证Audience
                        ValidateLifetime = true,//是否验证失效时间
                        ValidateIssuerSigningKey = true,//是否验证SecurityKey

                        ValidIssuer = jwtTokenOption.Issuer,
                        ValidAudience = jwtTokenOption.Audiece,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtTokenOption.SecurityKey)),
                        ClockSkew = TimeSpan.FromSeconds(0) //token过期后默认300s是有效的，0马上失效
                        //AudienceValidator = (m, n, z) =>
                        //{
                        //    //这里可以写自己定义的验证逻辑
                        //    //return m.
                        //    return true;
                        //},
                        //LifetimeValidator = (notBefore,expires,securityToken,validationParameters) =>
                        //{
                        //    //这里可以写自己定义的验证逻辑
                        //    return true;
                        //}
                    };
                    //options.Events = new JwtBearerEvents
                    //{
                    //    OnAuthenticationFailed = (context) =>
                    //    {
                    //        return Task.CompletedTask;
                    //    },
                    //    OnChallenge = (context) =>
                    //    {
                    //        return Task.CompletedTask;
                    //    },
                    //    OnForbidden = (context) =>
                    //    {
                    //        return Task.CompletedTask;
                    //    },
                    //    OnTokenValidated = (context) =>
                    //    {
                    //        return Task.CompletedTask;
                    //    },
                    //};
                });

            builder.Services.AddAuthorization(config =>
            {
                config.AddPolicy("MenuPolicy", (pollyBuider) =>
                {
                    pollyBuider.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                                .AddRequirements(new MenuAuthorizationRequirement());
                });
            });
            builder.Services.AddTransient<IAuthorizationHandler, MenuAuthorizationHandler>();
        }
        /// <summary>
        /// 使用鉴权和授权
        /// </summary>
        /// <param name="app"></param>
        public static void UseAuthorizationExt(this WebApplication app)
        {
            app.UseAuthentication();//鉴权，将请求携带的信息（token,session,cookies）解析到HttpContext.User中
            app.UseAuthorization();//授权，根据用户信息检查当前用户是否有权请求当前资源
        }
    }
}
